/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
 */

import { FileSet } from '@ohos/hvigor';
import { Stats } from 'fs';
import * as fse from 'fs-extra';
import path from 'path';

import { BuildArtifactConst, BuildDirConst } from '../const/build-directory-const.js';
import { RestoolLinkParamObj } from '../options/configure/restool-config-options.js';
import { FileUtil } from '../utils/file-util.js';

import { BaseCommandBuilder } from './base-command-builder.js';
import { RestoolBuilderInterface } from './restool-builder-interface.js';

export class RestoolCommandBuilder extends BaseCommandBuilder implements RestoolBuilderInterface {
  inputFiles: FileSet = new FileSet();
  outputFiles: FileSet = new FileSet();
  existsResourceDir = false;

  restoolLinkParamObj: RestoolLinkParamObj = {
    appScopeResources: undefined,
    moduleResourcesMap: new Map(),
    harResourcesMap: new Map(),
    outputPath: undefined,
    linkCommand: [],
  };

  constructor(executor: string) {
    super([]);
    this.commandList.push(executor);
    this.restoolLinkParamObj.linkCommand!.push(executor);
  }

  addInputVariantDir(inputVariantDir: string): RestoolBuilderInterface {
    if (!fse.existsSync(inputVariantDir)) {
      return this;
    }
    FileUtil.checkPathLength(inputVariantDir);
    this.commandList.push('-b');
    this.commandList.push(inputVariantDir);
    return this;
  }

  addInputDir(inputDir: string, inputType?: string): RestoolBuilderInterface {
    if (!fse.existsSync(inputDir)) {
      return this;
    }
    FileUtil.checkPathLength(inputDir);
    this.existsResourceDir = true;
    this.commandList.push('-i');
    this.commandList.push(inputDir);
    return this;
  }

  addEntryCompiledResource(inputDir: string): RestoolBuilderInterface {
    return this;
  }

  addAppScopeResourcesDir(inputDir: string): RestoolBuilderInterface {
    if (!fse.existsSync(inputDir)) {
      return this;
    }
    FileUtil.checkPathLength(inputDir);
    this.inputFiles.addEntry(inputDir);
    this.existsResourceDir = true;
    this.restoolLinkParamObj.appScopeResources = inputDir;
    return this;
  }

  addModuleResourcesMap(map: Map<string, string>): RestoolBuilderInterface {
    const tempMap = new Map<string, string>();
    map.forEach((compileOutDir, resourcesPath) => {
      if (!fse.existsSync(resourcesPath)) {
        return;
      }
      FileUtil.checkPathLength(resourcesPath);
      this.inputFiles.addEntry(resourcesPath);
      tempMap.set(resourcesPath, compileOutDir);
      this.existsResourceDir = true;
    });
    this.restoolLinkParamObj.moduleResourcesMap = tempMap;
    return this;
  }

  addHarResourcesMap(map: Map<string, string>): RestoolBuilderInterface {
    const tempMap = new Map<string, string>();
    map.forEach((compileOutDir, resourcesPath) => {
      if (!fse.existsSync(resourcesPath)) {
        return;
      }
      FileUtil.checkPathLength(resourcesPath);
      const stats: Stats = fse.statSync(resourcesPath);
      if (stats.isDirectory()) {
        this.inputFiles.addEntry(resourcesPath);
      } else {
        this.inputFiles.addEntry(resourcesPath, {
          isDirectory: false,
        });
      }
      tempMap.set(resourcesPath, compileOutDir);
      this.existsResourceDir = true;
    });
    this.restoolLinkParamObj.harResourcesMap = tempMap;
    return this;
  }

  addJsonFile(jsonFile: string): RestoolBuilderInterface {
    FileUtil.checkPathLength(jsonFile);
    this.inputFiles.addEntry(jsonFile, {
      isDirectory: false,
    });
    this.commandList.push('-j');
    this.commandList.push(jsonFile);

    this.restoolLinkParamObj.linkCommand!.push('-j');
    this.restoolLinkParamObj.linkCommand!.push(jsonFile);
    return this;
  }

  addModulePackName(packName: string): RestoolBuilderInterface {
    this.commandList.push('-p');
    this.commandList.push(packName);

    this.restoolLinkParamObj.linkCommand!.push('-p');
    this.restoolLinkParamObj.linkCommand!.push(packName);
    return this;
  }

  addOutputDir(outputDir: string): RestoolBuilderInterface {
    FileUtil.checkPathLength(outputDir);
    this.outputFiles.addEntry(outputDir);
    this.commandList.push('-o');
    this.commandList.push(outputDir);
    this.restoolLinkParamObj.outputPath = outputDir;
    return this;
  }

  addIdsPath(idsPath: string): RestoolBuilderInterface {
    FileUtil.checkPathLength(idsPath);
    this.restoolLinkParamObj.linkCommand!.push('--ids');
    this.restoolLinkParamObj.linkCommand!.push(idsPath);
    this.restoolLinkParamObj.idsMapPath = idsPath;
    return this;
  }

  addResTable(resTable: string): RestoolBuilderInterface {
    FileUtil.checkPathLength(resTable);
    if (this.commandList.includes(resTable)) {
      return this;
    }
    this.outputFiles.addEntry(resTable, {
      isDirectory: false,
    });
    this.commandList.push('-r');
    this.commandList.push(resTable);

    this.restoolLinkParamObj.linkCommand!.push('-r');
    this.restoolLinkParamObj.linkCommand!.push(resTable);
    return this;
  }

  forceDelete(): RestoolBuilderInterface {
    this.commandList.push('-f');
    this.restoolLinkParamObj.linkCommand!.push('-f');
    return this;
  }

  incremental(): RestoolBuilderInterface {
    this.commandList.push('-c');
    return this;
  }

  compressImage(): RestoolBuilderInterface {
    this.commandList.push('-z');
    return this;
  }

  addOutputBak(outputBak: string): RestoolBuilderInterface {
    FileUtil.checkPathLength(outputBak);
    this.commandList.push('-n');
    this.commandList.push(outputBak);
    return this;
  }

  addModules(modules: string): RestoolBuilderInterface {
    this.commandList.push('-m');
    this.commandList.push(modules);

    this.restoolLinkParamObj.linkCommand!.push('-m');
    this.restoolLinkParamObj.linkCommand!.push(modules);
    return this;
  }

  addStartId(startId: string): RestoolBuilderInterface {
    return this;
  }

  setIconCheck(enable: boolean): RestoolBuilderInterface {
    return this;
  }

  incrementalCompile(): RestoolBuilderInterface {
    this.restoolLinkParamObj.linkCommand!.push('-z');
    return this;
  }

  addDefinedIds(idsPath: string) {
    FileUtil.checkPathLength(idsPath);
    this.restoolLinkParamObj.linkCommand!.push('--defined-ids');
    this.restoolLinkParamObj.linkCommand!.push(path.resolve(idsPath, BuildArtifactConst.ID_DEFINED_JSON));
    return this;
  }

  addDefinedSysIds(definedIds: string) {
    return this;
  }
}
